/*
 * Copyright (c) Extreme Vision Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef LICENSE_PLATE_REC_H
#define LICENSE_PLATE_REC_H

#include <map>
#include <mutex>
#include "opencv2/core.hpp"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>

#include "evdeploy/core/ev_common_data.h"
#include "evdeploy/core/ev_deploy.h"
#include "evdeploy/utils/json/json.h"

namespace ev
{
    namespace algo
    {

        const std::vector<std::string> CH_PLATE_CODE = {
            "-", "R", "A", "W", "Y", "C", "D", "S", "F", "E", "H", "M", "B", "G", "K", "V", "J", "P", "U", "Z", "X", "Q", "N", "T", "L",
            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
            "急", "陕", "青", "贵", "津", "琼", "川", "藏", "澳", "新", "宁", "鲁", "领", "应", "豫", "港", "苏", "沪", "蒙", "学",
            "冀", "警", "皖", "京", "湘", "桂", "辽", "电", "黑", "吉", "赣", "晋", "甘", "闽", "云", "挂", "伊", "渝", "鄂", "粤", "浙"};

        const float MINIMUM_POSITIVE_FLOAT = 0.00000000000001;
        /**
         * @brief 车牌颜色类型
         * @param WHITE_P: 白牌
         * @param GREEN_P: 绿牌
         * @param YELLOW_P: 黄牌
         * @param BLUE_P: 蓝牌
         * @param BLACK_P: 黑牌
         * @param YELGRE_P: 黄绿牌
         * @param GRAY: 灰牌
         * @param BLUR: 模糊未知
         */
        enum class PLATE_COLOR_TYPE
        {
            WHITE_P = 0,
            GREEN_P = 1,
            YELLOW_P = 2,
            BLUE_P = 3,
            BLACK_P = 4,
            YELGRE_P = 5,
            GRAY = 6,
            BLUR = 7,
        };

        static std::map<PLATE_COLOR_TYPE, std::string> COLOR_NAME = {
            {PLATE_COLOR_TYPE::WHITE_P, "WHITE"},
            {PLATE_COLOR_TYPE::GREEN_P, "GREEN"},
            {PLATE_COLOR_TYPE::YELLOW_P, "YELLOW"},
            {PLATE_COLOR_TYPE::BLUE_P, "BLUE"},
            {PLATE_COLOR_TYPE::BLACK_P, "BLACK"},
            {PLATE_COLOR_TYPE::YELGRE_P, "YELLOW_GREEN"},
            {PLATE_COLOR_TYPE::GRAY, "GRAY"},
            {PLATE_COLOR_TYPE::BLUR, "BLUR"}};

        /**
         * @brief 车牌层数
         * @param DOUBLE_LAYER: 双层牌
         * @param SINGLE_LAYER: 单层牌
         * @param BLUR: 模糊未知
         */
        enum class PLATE_LAYER_TYPE
        {
            //'双层',‘单层’,'模糊'
            DOUBLE_LAYER = 0,
            SINGLE_LAYER = 1,
            BLUR = 2,
        };

        static std::map<PLATE_LAYER_TYPE, std::string> LAYER_NAME = {
            {PLATE_LAYER_TYPE::DOUBLE_LAYER, "DOUBLE"},
            {PLATE_LAYER_TYPE::SINGLE_LAYER, "SINGLE"},
            {PLATE_LAYER_TYPE::BLUR, "BLUR"}};

        class LicensePlateRec
        {
        public:
            LicensePlateRec(std::string engine, std::string uuid);

            ~LicensePlateRec();
            /**
             * @brief 车牌识别
             * @param[in] input_mat: input license plate image, cropped small image assumed, not original big image
             * @param[out] out_json: recognization result wrapped in json format,
             * e.g.,
             * {
             *      "plate_color" : "BLUE",
             *      "plate_color_score" : 0.99999994039535522,
             *      "plate_layer" : "SINGLE",
             *      "plate_layer_score" : 0.99998736381530762,
             *      "plate_ocr" : "黑L00000",
             *      "plate_ocr_score" : 0.97750365734100342
             * }
             * @return EVStatus
             */
            EVStatus Run(cv::Mat &input_mat, ev::Value &out_json);

        private:
            std::string m_uuid;
	        static std::mutex m_mutex;
	        std::string m_engine;
        };
    } // namespace algo
} // namespace ev

#endif
